<?php

namespace App\Http\Requests\Admin\Panx\Device;

use App\Http\Controllers\Admin\Panx\DeviceController;
use App\Http\Requests\ApiRequest;
use App\Rules\ArrayDBUnique;
use App\Services\Utils\ApiChecker;
use Illuminate\Foundation\Http\FormRequest;
use Tests\Feature\App\Admin\Panx\DeviceControllerTest;

/**
 * @property int purchase_device_id
 * @property int num
 * @property mixed customer_id
 * @property mixed sold_at
 * @property array uuids
 * @property string operator
 * @property array skin_detector_ids
 */
class DeviceSellRequest extends ApiRequest
{
    use ApiChecker;

    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     * @throws \Exception
     */
    public function rules()
    {
        $data = [
            'purchase_device_id' => 'required|int|min:1|max:'.self::MAX_INT,
            'customer_id'        => 'required|int|min:1|max:'.self::MAX_INT,
            'num'                => 'required|int|min:1|max:'.self::MAX_INT,
            'sold_at'            => 'required|date',
            'uuids'              => 'required|array',

            // 这种数组检查会多次查询数据库
//            'uuids.*'            => 'required|unique:device_accounts,uuid',

            'uuids.*'            => [
                'required', 'string', 'max:'.self::MAX_STRING,  new ArrayDBUnique($this->all(), 'device_accounts', 'uuid')
            ],

            'operator'           => 'nullable|string|max:'.self::MAX_STRING,
            'skin_detector_ids'  => 'sometimes|required|array',
            'skin_detector_ids.*'=> 'sometimes|required|int|min:1|max:'.self::MAX_INT,
         ];

        $this->checkUUIDsSizeEqualNum();
        $this->checkUniqueUUIDs();

        return $data;
    }

    /**
     * @return array
     */
//    public function messages()
//    {
//        return [
//            'purchase_device_id.*' => '采购设备的id必须是数值',
//            'customer_id.*'        => '代理客户的id必须是数值',
//            'num.*'                => '卖出的数量必须是数值',
//            'sold_at.*'            => '卖出的日期必须是日期',
//        ];
//    }

    /**
     * @test
     * @see DeviceControllerTest::test_admin_sell_device_add_uuids()
     * @throws \Exception
     */
    private function checkUniqueUUIDs()
    {
        $uuids_count = isset($this->uuids) ? count($this->uuids) : null;
        if ($uuids_count) {
            $unique_count = count(array_unique($this->uuids));
            $this->checkParamError($unique_count === $uuids_count, trans('admin.same_uuid'));
        }
    }

    /**
     * @see DeviceController::normalizeUUIDs()
     * @throws \Exception
     */
    private function checkUUIDsSizeEqualNum()
    {
        $num   = (int) $this->num;
        $count = isset($this->uuids) ? count($this->uuids) : null;

        if($count) {
            $this->checkParamError($num === $count, '机器编号数量必须与购买数量一致');
        }
    }
}
